import { timeDay, timeMinute } from 'd3-time';
import moment from 'moment';
import 'moment/locale/zh-cn';
import { createContext, useEffect, useState, useRef } from 'react';
moment.locale('zh-cn');

const SchCtx = createContext({
  dateUnit: 'DAY',
  cellWidth: 60,
  beginTime: null,
  timeRange: [],
  resources: [],
  normalResources: [],
  setDateUnit: () => {},
  setBeginTime: () => {},
  setSelectItems: () => {},
  selectEnabled: false,
  setSelectEnabled: () => {},
  onPrev: undefined,
  onNext: undefined,
  onReset: undefined,
  selectItems: {
    resource: null,
    from: '',
    to: '',
  },
});

const SchProvider = ({ children, data: resources, onScreenshotChange }) => {
  const [dateUnit, setDateUnit] = useState('DAY');
  const [beginTime, setBeginTime] = useState(Date.now());
  const [timeRange, setTimeRange] = useState([]);
  const [selectItems, setSelectItems] = useState(null);
  const [selectEnabled, setSelectEnabled] = useState(false);
  const [normalResources, setNormalResources] = useState([]);
  const [cellWidth, setCellWidth] = useState(60);
  const initialRender = useRef(true);
  useEffect(() => {
    const schTableBox = document.querySelectorAll('.sch-table-box')[0];
    if (timeRange.length && schTableBox) {
      const boxWidth = schTableBox.getBoundingClientRect().width - 15;
      let cellWidth = 0;
      if (dateUnit == 'MONTH') {
        cellWidth = 60;
      } else {
        cellWidth = (boxWidth - 153) / timeRange.length;
      }
      setCellWidth(cellWidth.toFixed(2));
    }
  }, [timeRange, dateUnit]);
  useEffect(() => {
    const eventColor = {
      1: 'rgba(255, 157, 30, 0.6)',
      2: 'rgba(25, 102, 255, 0.6)',
      3: 'rgba(204, 204, 204, 0.6)',
    };
    const normalData = resources
      .reduce(
        (next, { card, details = [], ...remainInfo }) => [
          ...next,
          ...(details ? details.map((info) => ({ ...remainInfo, ...info, card, details })) : [{...remainInfo, details, card }]),
        ],
        [],
      )
      .reduce(
        (
          next,
          {
            details,
            cid = '',
            card,
            driverName = '',
            taskTagName = '',
            creatorName = '',
            ...restInfo
          },
        ) =>
          next.find(({ card: prevCard }) => prevCard === card)
            ? next.map(({ card: prevCard, events, ...restEventInfo }) =>
                prevCard === card
                  ? {
                      card: prevCard,
                      ...restEventInfo,
                      events: [
                        ...(events || []),
                        ...(details
                          ? [
                              {
                                cid,
                                card,
                                driverName,
                                taskTagName,
                                creatorName,
                                ...restInfo,
                                bgColor: eventColor[restInfo.status],
                              },
                            ]
                          : []),
                      ],
                    }
                  : { card: prevCard, events, ...restEventInfo },
              )
            : [
                ...next,
                {
                  cid,
                  card,
                  driverName,
                  taskTagName,
                  creatorName,
                  ...restInfo,
                  events: details
                    ? [
                        {
                          cid,
                          card,
                          driverName,
                          taskTagName,
                          creatorName,
                          ...restInfo,
                          bgColor: eventColor[restInfo.status] || '',
                        },
                      ]
                    : [],
                },
              ],
        [],
      );
    setNormalResources(normalData);
  }, [resources]);
  useEffect(() => {
    setSelectItems(null);
  }, [dateUnit]);
  const onPrev = () => {
    setSelectItems(null);
    let newDate = +moment(beginTime).subtract(1, 'day');
    if (dateUnit === 'WEEK') {
      newDate = +moment(beginTime).subtract(1, 'week');
    }
    if (dateUnit === 'MONTH') {
      newDate = +moment(beginTime).subtract(1, 'month');
    }
    setBeginTime(newDate);
  };
  const onNext = () => {
    setSelectItems(null);
    let newDate = +moment(beginTime).add(1, 'day');
    if (dateUnit === 'WEEK') {
      newDate = +moment(beginTime).add(1, 'week');
    }
    if (dateUnit === 'MONTH') {
      newDate = +moment(beginTime).add(1, 'month');
    }
    setBeginTime(newDate);
  };
  const onReset = () => {
    setSelectItems(null);
    setBeginTime(Date.now());
  };
  useEffect(() => {
    if (dateUnit === 'WEEK') {
      const from = moment(beginTime).startOf('isoWeek').toDate();
      const to = moment(beginTime).endOf('isoWeek').toDate();
      const ranges = timeDay.range(from, to, 1);
      setTimeRange(ranges);
      onScreenshotChange({ type: 'week', from, to });
      return;
    }
    if (dateUnit === 'MONTH') {
      const from = moment(beginTime).startOf('month').toDate();
      const to = moment(beginTime).endOf('month').toDate();
      const ranges = timeDay.range(from, to, 1);
      setTimeRange(ranges);
      onScreenshotChange({ type: 'month', from, to });
      return;
    }
    if (dateUnit === 'LIST') {
      const from = '';
      const to = '';
      onScreenshotChange({ type: 'list', from, to });
      return;
    }
    const from = moment(beginTime).startOf('day').add(8, 'hours').toDate();
    const to = moment(beginTime).startOf('day').add(23, 'hours').toDate();
    const ranges = timeMinute.range(from, to, 30);
    setTimeRange(ranges);
    if (initialRender.current) {
      initialRender.current = false;
    } else {
      onScreenshotChange({ type: 'day', from, to });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [beginTime, dateUnit]);
  return (
    <SchCtx.Provider
      value={{
        beginTime,
        cellWidth,
        dateUnit,
        timeRange,
        resources,
        normalResources,
        selectItems,
        selectEnabled,
        setDateUnit,
        setBeginTime,
        setSelectItems,
        setSelectEnabled,
        onPrev,
        onNext,
        onReset,
      }}
    >
      {children}
    </SchCtx.Provider>
  );
};

export const ScheduleContext = SchCtx;

export default SchProvider;
